package com.github.elliot.gatewaycenter.security.filters;

import com.github.elliot.gatewaycenter.common.constant.AuthConstant;
import com.github.elliot.gatewaycenter.domain.AdminUserPO;
import com.github.elliot.gatewaycenter.security.converter.RefreshTokenAuthenticationConverter;
import com.github.elliot.gatewaycenter.security.handlers.CustomServerAuthenticationFailureHandler;
import com.github.elliot.gatewaycenter.security.handlers.CustomServerAuthenticationSuccessHandler;
import com.github.elliot.gatewaycenter.security.jwt.JwtTokenGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AbstractUserDetailsReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

public class RefreshTokenAuthenticationFilter extends AuthenticationWebFilter {

    public RefreshTokenAuthenticationFilter(AbstractUserDetailsReactiveAuthenticationManager refreshTokenAuthenticationManager,
                                            CustomServerAuthenticationSuccessHandler customServerAuthenticationSuccessHandler,
                                            CustomServerAuthenticationFailureHandler customServerAuthenticationFailureHandler,
                                            RefreshTokenAuthenticationConverter refreshTokenAuthenticationConverter) {
        super(refreshTokenAuthenticationManager);
        this.setServerAuthenticationConverter(refreshTokenAuthenticationConverter);
        this.setRequiresAuthenticationMatcher(ServerWebExchangeMatchers.pathMatchers(AuthConstant.REFRESH_URL));
        this.setAuthenticationFailureHandler(customServerAuthenticationFailureHandler);
        this.setAuthenticationSuccessHandler(customServerAuthenticationSuccessHandler);
    }

    @Component
    public static class RefreshTokenAuthenticationManager extends AbstractUserDetailsReactiveAuthenticationManager {

        @Autowired
        private JwtTokenGenerator jwtTokenGenerator;

        @Override
        public Mono<Authentication> authenticate(Authentication authentication) {
            AdminUserPO adminUserPo = (AdminUserPO) authentication.getPrincipal();
            UsernamePasswordAuthenticationToken authenticated =
                    UsernamePasswordAuthenticationToken.authenticated(adminUserPo, null, adminUserPo.getAuthorities());
            return Mono.just(authenticated);
        }

        @Override
        protected Mono<UserDetails> retrieveUser(String username) {
            return null;
        }

    }
}
